
local BlockInputField = import("./BlockInputField.lua");
local FieldSpace = import("./Field/Space.lua");

local InputFieldContainer = commonlib.inherit(BlockInputField);

InputFieldContainer:Property("InputStatementContainer", false, "IsInputStatementContainer"); -- 是否是输入语句容器

function InputFieldContainer:ctor()
    self.__input_field_list__ = {};
end

function InputFieldContainer:Init(block, isFillFieldSpace)
    InputFieldContainer._super.Init(self, block);
    
    -- 默认填充一个空白字段
    if (isFillFieldSpace) then
        table.insert(self.__input_field_list__, FieldSpace:new():Init(self:GetBlock()));
    end

    self:SetType("__input_field_container__");
    
    return self;
end

function InputFieldContainer:AddInputField(inputField, isFillFieldSpace, index)
    if (not inputField) then return end 

    if (index) then
        table.insert(self.__input_field_list__, index, inputField);
    else
        table.insert(self.__input_field_list__, inputField);
    end
    -- inputField:SetInputFieldContainer(self);
    if (not isFillFieldSpace) then return end 

    if (index) then
        table.insert(self.__input_field_list__, index + 1, FieldSpace:new():Init(self:GetBlock()));
    else
        table.insert(self.__input_field_list__, FieldSpace:new():Init(self:GetBlock()));
    end
end

function InputFieldContainer:DeleteInputField(inputField)
    for i, item in ipairs(self.__input_field_list__) do
        if (item == inputField) then
            local nextItem = self.__input_field_list__[i + 1];
            table.remove(self.__input_field_list__, i);
            if (nextItem:GetType() == "field_space") then
                table.remove(self.__input_field_list__, i);
            end
            return ;
        end 
    end
end

function InputFieldContainer:GetInputFieldIndex(inputField)
    for i, item in ipairs(self.__input_field_list__) do
        if (item == inputField) then return i end 
    end
end

function InputFieldContainer:GetInputFieldList()
    return self.__input_field_list__;
end

function InputFieldContainer:IsEmpty()
    return #self.__input_field_list__ == 0;
end

function InputFieldContainer:GetPrevNextInputFieldContainer()
    local block = self:GetBlock();
    for i, inputFieldContainer in ipairs(block.__input_field_container_list__) do
        if (inputFieldContainer == self) then
            return block.__input_field_container_list__[i - 1], block.__input_field_container_list__[i + 1];
        end
    end
    return nil, nil;
end

function InputFieldContainer:UpdateWidthHeightUnitCount()
    local widthUnitCount, heightUnitCount = 0, 0, 0, 0;
    for _, inputField in ipairs(self.__input_field_list__) do
        local inputFieldMaxWidthUnitCount, inputFieldMaxHeightUnitCount, inputFieldWidthUnitCount, inputFieldHeightUnitCount = inputField:UpdateWidthHeightUnitCount();
        inputFieldWidthUnitCount, inputFieldHeightUnitCount = inputFieldWidthUnitCount or inputFieldMaxWidthUnitCount, inputFieldHeightUnitCount or inputFieldMaxHeightUnitCount;
        inputField:SetWidthHeightUnitCount(inputFieldWidthUnitCount, inputFieldHeightUnitCount);
        inputField:SetMaxWidthHeightUnitCount(inputFieldMaxWidthUnitCount, inputFieldMaxHeightUnitCount);
        widthUnitCount = widthUnitCount + inputFieldWidthUnitCount;
        heightUnitCount = math.max(heightUnitCount, inputFieldHeightUnitCount);
    end
    
    self:SetWidthHeightUnitCount(widthUnitCount, heightUnitCount);
    self:SetMaxWidthHeightUnitCount(widthUnitCount, heightUnitCount);
    return widthUnitCount, heightUnitCount;
end

function InputFieldContainer:UpdateLeftTopUnitCount()
    local widthUnitCount, heightUnitCount = self:GetWidthHeightUnitCount();
    local offsetX, offsetY = self:GetLeftTopUnitCount();
    for _, inputField in ipairs(self.__input_field_list__) do
        local inputFieldWidthUnitCount, inputFieldHeightUnitCount = inputField:GetWidthHeightUnitCount();
        inputField:SetLeftTopUnitCount(offsetX, offsetY + (heightUnitCount - inputFieldHeightUnitCount) / 2);
        inputField:UpdateLeftTopUnitCount();
        offsetX = offsetX + inputFieldWidthUnitCount;
    end
end

function InputFieldContainer:ConnectionBlock(block)
    for _, inputField in ipairs(self.__input_field_list__) do
        if (inputField:ConnectionBlock(block)) then return true end
    end
    return false;
end

function InputFieldContainer:GetMouseUI(x, y)
    local left, top = self:GetLeftTop();
    local width, height = self:GetWidthHeight();
    local block_width = self:GetBlock():GetWidthHeight();
    
    -- 区域内判断  
    width = math.max(width, block_width);   -- 容器宽度可能小于块宽度, 字段未填满, 输入语句空块
    if (x < left or x > (left + width) or y < top or y > (top + height)) then return end

    -- 输入字段判断
    for _, inputField in ipairs(self.__input_field_list__) do
        local ui = inputField:GetMouseUI(x, y);
        if (ui) then return ui end
    end

    -- 是语句字段则直接返回
    if (self:IsInputStatementContainer()) then return nil end 
    
    -- 内联字段在区域内, 返回当前UI
    return self;
end

function InputFieldContainer:Render()
    if (not self:IsInputStatementContainer()) then
        local leftUnitCount, topUnitCount = self:GetLeftTopUnitCount();
        local widthUnitCount, heightUnitCount = self:GetWidthHeightUnitCount();
        local block = self:GetBlock();
        local blockWidthUnitCount, blockHeightUnitCount = block:GetWidthHeightUnitCount();
        if (block:IsOutput()) then 
            widthUnitCount = blockWidthUnitCount - blockHeightUnitCount;
        else
            widthUnitCount = blockWidthUnitCount;
        end
        self:SetBrushColor(self:GetBlock():GetColor());
        self:DrawRectangle(widthUnitCount, heightUnitCount, leftUnitCount, topUnitCount, not self:GetBlock():IsOutput());
    end

    for _, inputField in ipairs(self.__input_field_list__) do inputField:Render() end
end

function InputFieldContainer:ForEach(callback)
    for _, inputField in ipairs(self.__input_field_list__) do
        inputField:ForEach(callback);
    end
end

function InputFieldContainer:SaveToXmlNode()
    local xmlNode = {name = "InputFieldContainer", attr = {index = self:GetIndex()}};
    return xmlNode;
end

function InputFieldContainer:LoadFromXmlNode(xmlNode)
end

function InputFieldContainer:GetIndex()
    local block = self:GetBlock();
    for i, item in ipairs(block.__input_field_container_list__) do
        if (item == self) then return i end
    end
end


function InputFieldContainer:IsSpaceFieldContainer()
    for _, input_field in ipairs(self.__input_field_list__) do
        if (input_field:GetType() ~= "field_space") then
            return false;
        end
    end
    return true;
end

function InputFieldContainer:TrimSpaceField()
    local head, tail = 1, #self.__input_field_list__;
    while (head <= tail) do
        while (tail > 0) do
            local tail_field = self.__input_field_list__[tail];
            if (tail_field:GetType() == "field_space") then
                self.__input_field_list__[tail] = nil;
                tail = tail - 1;
            else
                break;
            end
        end
        if (tail < 1 or head > tail) then break end 
        local head_field = self.__input_field_list__[head];
        if (head_field:GetType() == "field_space") then
            self.__input_field_list__[head], self.__input_field_list__[tail] = self.__input_field_list__[tail], self.__input_field_list__[head];
        else 
            head = head + 1;
        end
    end
end

return InputFieldContainer;